package com.rzico.sbl.ui.manual

import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
import android.widget.ImageView
import android.widget.RadioGroup
import androidx.core.view.isVisible
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import com.google.gson.Gson
import com.jeremyliao.liveeventbus.LiveEventBus
import com.jeremyliao.liveeventbus.utils.observe
import com.lzg.extend.jackson.JsonUtil
import com.lzy.okgo.model.HttpMethod
import com.rzico.sbl.R
import com.rzico.sbl.databinding.ActivityManualRepairBinding
import com.rzico.sbl.model.BaseUrl
import com.rzico.sbl.model.CommonData
import com.rzico.sbl.model.GoodsData
import com.rzico.sbl.model.ManualBarrel
import com.rzico.sbl.model.OrderGoods
import com.rzico.sbl.other.showManualDialog
import com.rzico.sbl.other.userRole
import com.rzico.sbl.ui.goods.GoodsActivity
import com.rzico.sbl.ui.member.MemberDetailActivity
import com.rzico.sbl.ui.member.MemberTicketActivity
import com.rzico.sbl.ui.order.OrderShipWhereActivity
import com.rzico.sbl.ui.order.OrderShipWhoActivity
import com.rzico.sbl.viewmodel.ManualViewModel
import com.xinnuo.common.decoration.DividerLRDecoration
import com.xinnuo.common.extend.*
import com.xinnuo.common.helper.*
import com.xinnuo.common.listener._TextWatcher
import com.xinnuo.common.view.FullyLinearLayoutManager
import com.xinnuo.common_ui.base.BaseActivity
import com.xinnuo.common_ui.base.addItems
import com.xinnuo.common_ui.glideExt.loadImage
import com.xinnuo.common_ui.utils.*
import com.xinnuo.slimadapter.SlimAdapter
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.json.JSONObject

class ManualRepairActivity : BaseActivity(R.layout.activity_manual_repair) {

    private val mBinding by lazy {
        ActivityManualRepairBinding.bind(getRootView())
    }

    private lateinit var mBarrelAdapter: SlimAdapter
    private val mPayList = ArrayList<CommonData>()          //付款方式
    private val mBrandList = ArrayList<ManualBarrel>()      //品牌列表
    private val mBrandCheckList = ArrayList<ManualBarrel>() //选中品牌

    private lateinit var mReceiverId: String //收货id
    private lateinit var mCardId: String     //会员卡id
    private lateinit var mMemberId: String   //会员id
    private lateinit var mPayPlugin: String  //付款插件

    private val mGoodsCount = MutableLiveData(0)
    private var mPayStatus = "paid" //付款状态
    private var mPayMethod = ""     //付款方式
    private var mShopId = ""        //配送店铺ID
    private var mAdminId = ""       //配送员ID
    private var mAdminName = ""     //配送员名称
    private var mReceiveName = ""   //收货人
    private var mReceivePhone = ""  //收货电话
    private var mReceiveAdress = "" //收货地址
    private var mReceiveLat = ""    //收货维度
    private var mReceiveLng = ""    //收货经度
    private var mCreateDate = ""    //下单时间
    private var mDeliveryDate = ""  //送达时间
    private var exchangeEnable = false //是否抵扣水票

    override fun getViewModel() = get<ManualViewModel>()

    override fun initData() {
        initTitle(title = "补单编辑")

        initLayout()

        getData()

        mCardId.notEmpty {
            getViewModel()
                .ticketCount(this)
        }
    }

    private fun initLayout() {
        mBinding
            .manualList
            .apply {
                isNestedScrollingEnabled = false
                layoutManager = FullyLinearLayoutManager(getIContext())

                mAdapter = SlimAdapter.creator()
                    .register<OrderGoods>(R.layout.item_manual_edit_list) { jector, bean, _ ->
                        jector.apply {
                            text(R.id.item_manual_name, bean.name)
                            text(R.id.item_manual_price, bean.price.formatDecimal())
                            text(R.id.item_manual_num, "x${bean.quantity}")

                            with<ImageView>(R.id.item_manual_img) {
                                it.loadImage(bean.thumbnail)
                            }

                            clicked(R.id.item_manual_edit) {
                                showManualDialog(
                                    name = bean.name,
                                    price = bean.price.orEmpty("0.00"),
                                    defaultNum = bean.quantity,
                                    isForced = true,
                                    onSure = { price, num ->
                                        cartModify(bean.id, price, num)
                                    }
                                )
                            }

                            longClicked {
                                cartDelete(bean.id)
                                true
                            }
                        }
                    }
                    .attachTo(this)
            }

        mBinding
            .barrelList
            .apply {
                isNestedScrollingEnabled = false
                layoutManager = FullyLinearLayoutManager(getIContext())

                addItemDecoration(
                    DividerLRDecoration(
                        spaceL = 0f,
                        spaceR = 0f,
                        hasFooter = false
                    )
                )

                mBarrelAdapter = SlimAdapter.creator()
                    .register<ManualBarrel>(R.layout.item_manual_barrel) { jector, bean, index ->

                        // 解构声明
                        val (_, name, count) = bean

                        jector.apply {
                            text(R.id.item_manual_name, name)

                            // 回桶数量
                            with<EditText>(R.id.item_manual_count) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.setText(count)
                                it.setSelection(it.text.length)

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.returnQuantity = s.toString()
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            clicked(R.id.item_manual_del) {
                                mBrandCheckList.removeAt(index)
                                mBarrelAdapter.apply {
                                    notifyItemRemoved(index)
                                    notifyItemRangeChanged(index, mBrandCheckList.size - index)
                                }
                            }
                        }
                    }
                    .attachTo(this)
            }
    }

    override fun initListener() {
        mPayPlugin = "cashPayPlugin"
        mReceiverId = intent.getExtra("receiverId")
        mCardId = intent.getExtra("cardId")
        mMemberId = intent.getExtra("memberId")
        mReceiveName = intent.getExtra("consignee")
        mReceivePhone = intent.getExtra("phone")
        mReceiveAdress = intent.getExtra("address")

        mBinding.apply {
            manualRb1.setCompoundDrawable(
                leftSize = 16f,
                leftDrawable = R.drawable.manual_ticket_selector
            )

            manualRb2.setCompoundDrawable(
                leftSize = 16f,
                leftDrawable = R.drawable.manual_ticket_selector
            )
            manualName.text = "$mReceiveName  $mReceivePhone"
            manualAdress.text = mReceiveAdress
            manualMember.isVisible = mCardId.isNotEmpty() && userRole in "1,2"
            manualTicketsLl.isVisible = mCardId.isNotEmpty()

            manualCall.oneClick {
                mReceivePhone.notEmpty {
                    showBottomPhoneDialog(this)
                }
            }

            manualAdress.longClick {
                mReceiveAdress
                    .notEmpty {
                        copyStringToClip(this)
                        showToast("地址复制成功！")
                    }
            }

            manualAdressCopy.oneClick {
                mReceiveAdress
                    .notEmpty {
                        copyStringToClip(this)
                        showToast("地址复制成功！")
                    }
            }

            manualMember.oneClick {
                (mCardId.isNotEmpty()
                        && mMemberId.isNotEmpty())
                    .condition {
                        startActivityEx<MemberDetailActivity>(
                            "cardId" to mCardId,
                            "memberId" to mMemberId
                        )
                    }
            }

            manualTicketsLl.oneClick {
                mCardId.notEmpty {
                    startActivityEx<MemberTicketActivity>(
                        "cardId" to mCardId,
                        "memberId" to mMemberId
                    )
                }
            }

            manualGroup.setOnCheckedChangeListener(this@ManualRepairActivity)

            // 付款方式
            manualPay.oneClick {
                mPayList
                    .isNotEmpty()
                    .conditionElse(
                        actionTrue = ::showActionDialog,
                        actionFalse = { getViewModel().getPayment() }
                    )
            }

            // 配送站
            manualWhere.oneClick {
                startActivityEx<OrderShipWhereActivity>(
                    "lat" to mReceiveLat,
                    "lng" to mReceiveLng
                )
            }

            // 配送员
            manualWho.oneClick {
                mShopId.ifEmpty {
                    showToast("请选择配送站点")
                    return@oneClick
                }

                startActivityEx<OrderShipWhoActivity>("shopId" to mShopId)
            }

            // 下单时间
            manualCreate.oneClick {
                val initYear =
                    TimeHelper
                        .getInstance()
                        .run {
                            getYearOfDate(stringDateShort)
                        }

                showTimeDialog(
                    minYearValue = initYear - 1,
                    maxYearValue = initYear,
                    count = 5,
                    title = "请选择下单时间",
                    isCurrentDate = true,
                    isAfterLimited = true
                ) { _, _, _, _, _, hint ->
                    mCreateDate =
                        hint.toFormat(
                            sFormat = "yyyy-MM-dd HH:mm",
                            eFormat = "yyyy-MM-dd HH:mm:ss"
                        )

                    mDeliveryDate.notEmpty {
                        this.isBefore(
                            mCreateDate,
                            "yyyy-MM-dd HH:mm:ss"
                        ).condition {
                            mCreateDate = ""

                            lifecycleScope.launch {
                                delay(400)

                                showOneHintDialog(
                                    hint = "下单时间不能晚于送达时间"
                                )
                            }

                            return@showTimeDialog
                        }
                    }

                    manualCreate.setRightString(mCreateDate)
                }
            }

            // 送达时间
            manualDeliver.oneClick {
                val initYear =
                    TimeHelper
                        .getInstance()
                        .run {
                            getYearOfDate(stringDateShort)
                        }

                showTimeDialog(
                    minYearValue = initYear - 1,
                    maxYearValue = initYear,
                    count = 5,
                    title = "请选择送达时间",
                    isCurrentDate = true,
                    isAfterLimited = true
                ) { _, _, _, _, _, hint ->
                    mDeliveryDate =
                        hint.toFormat(
                            sFormat = "yyyy-MM-dd HH:mm",
                            eFormat = "yyyy-MM-dd HH:mm:ss"
                        )

                    mCreateDate.notEmpty {
                        mDeliveryDate.isBefore(
                            this,
                            "yyyy-MM-dd HH:mm:ss"
                        ).condition {
                            mDeliveryDate = ""

                            lifecycleScope.launch {
                                delay(400)

                                showOneHintDialog(
                                    hint = "送达时间不能早于下单时间"
                                )
                            }

                            return@showTimeDialog
                        }
                    }

                    manualDeliver.setRightString(mDeliveryDate)
                }
            }

            // 添加商品
            manualAdd.oneClick {
                startActivityEx<GoodsActivity>("mode" to "single")
            }

            // 添加回桶
            manualBarrel.oneClick {
                mBrandList
                    .isEmpty()
                    .conditionElse(
                        actionTrue = {
                            getBrandList { showBrandDialog() }
                        },
                        actionFalse = ::showBrandDialog
                    )
            }

            // 提交订单
            btSubmit.oneClick {
                when {
                    mList.isEmpty() -> {
                        showToast("请添加报单商品")
                        return@oneClick
                    }

                    mPayMethod.isEmpty() -> {
                        showToast("请选择付款方式")
                        return@oneClick
                    }

                    mShopId.isEmpty() -> {
                        showToast("请选择配送站点")
                        return@oneClick
                    }

                    mAdminId.isEmpty() -> {
                        showToast("请选择配送人员")
                        return@oneClick
                    }

                    mCreateDate.isEmpty() -> {
                        showToast("请选择下单时间")
                        return@oneClick
                    }

                    mDeliveryDate.isEmpty() -> {
                        showToast("请选择送达时间")
                        return@oneClick
                    }
                }

                checkTicket {
                    checkBarrel {
                        submit()
                    }
                }
            }
        }

        // 观察付款方式
        getViewModel()
            .mPayEvent
            .observe(getLifecycleOwner()) {
                mPayList.addItems(it)
                showActionDialog()
            }

        // 观察应收金额
        getViewModel()
            .mTotalEvent
            .observe(getLifecycleOwner()) {
                if (it == 0.0) {
                    mPayPlugin = "cashPayPlugin"
                    mPayMethod = "eleTicket"
                    mBinding.manualPay.gone()
                } else {
                    mPayMethod = ""
                    mBinding.manualPay.visible()
                    mBinding.manualPay.setRightString("")
                }
            }

        // 观察商品列表
        mGoodsCount
            .observe(getLifecycleOwner()) { length ->
                mBinding
                    .manualGoodsLl
                    .isVisible = length > 0

                mList.notEmpty {
                    mBinding
                        .manualNum
                        .text = sumOf {
                        it as OrderGoods
                        it.quantity.intValue
                    }.toString()

                    mBinding
                        .manualAmount
                        .text = sumOf {
                        it as OrderGoods
                        it.quantity.intValue * it.price.doubleValue
                    }.formatDecimal()
                }
            }

        // 观察会有水票总数
        getViewModel()
            .mTicketEvent
            .observe(this) {
                mBinding
                    .manualTickets
                    .text = it.toString()
            }

        // 观察配送方式
        observe<String>("orderShip") {
            val items = it.split(",")
            when (items[0]) {
                "shop" -> {
                    mShopId = items[1]
                    mAdminId = ""
                    mAdminName = ""

                    mBinding.manualWhere.setRightString(items[2])
                    mBinding.manualWho.setRightString("")
                }

                "admin" -> {
                    mAdminId = items[1]
                    mAdminName = items[2]

                    mBinding.manualWho.setRightString(items[2])
                }
            }
        }

        // 观察添加商品
        LiveEventBus
            .get("manualGoods", GoodsData::class.java)
            .observe(this) {
                getViewModel()
                    .delay {
                        showManualDialog(
                            name = it.name,
                            price = it.price,
                            isForced = true,
                            onSure = { price, count ->
                                cartAdd(it.productId, price, count)
                            }
                        )
                    }
            }
    }

    /**
     * 付款方式
     */
    private fun showActionDialog() {
        val items =
            mPayList
                .filterNot { it.id == "signature" }
                .map { it.name.orEmpty() }
                .toTypedArray()

        showActionDialog(*items) { index, hint ->
            mPayMethod = mPayList[index].id
            mBinding.manualPay.setRightString(hint)

            mPayPlugin = conditionIf(
                mPayMethod == "monthly",
                "monthPayPlugin",
                "cashPayPlugin"
            )
        }
    }

    private fun checkTicket(onNext: () -> Unit) {
        mList
            .any {
                it as OrderGoods
                it.type == "dummy" && it.subType == "water"
            }
            .conditionElse(
                actionTrue = {
                    showHintDialog(
                        hint = "是否确认给客户添加水票？",
                        onSure = {
                            getViewModel()
                                .delay(
                                    time = 200,
                                    onResult = onNext
                                )
                        }
                    )
                },
                actionFalse = onNext
            )
    }

    private fun checkBarrel(onNext: () -> Unit) {
        mBrandCheckList
            .none { it.returnQuantity.intValue > 0 }
            .conditionElse(
                actionTrue = {
                    showHintDialog(
                        hint = "您还没有添加回桶信息，是否确认提交订单？",
                        onSure = {
                            getViewModel()
                                .delay(
                                    time = 200,
                                    onResult = onNext
                                )
                        }
                    )
                },
                actionFalse = onNext
            )
    }

    /**
     * 提交数据
     */
    private fun submit() {
        mBrandCheckList.forEach {
            if (it.returnQuantity.intValue == 0) {
                it.returnQuantity = "0"
            }
        }

        getViewModel()
            .goodsEdit(
                BaseUrl.manuSub,
                "shippingMethod" to "warehouse",
                "pledge" to "0",
                "pledgeQuantity" to "0",
                "exchangeEnable" to exchangeEnable,
                "receiverId" to mReceiverId,
                "memberId" to mMemberId,
                "paymentPluginId" to mPayPlugin,
                "payStatus" to mPayStatus,
                "payMethod" to mPayMethod,
                "shopId" to mShopId,
                "adminId" to mAdminId,
                "createDate" to mCreateDate,
                "deliveryDate" to mDeliveryDate,
                "barrelBody" to Gson().toJson(mBrandCheckList),
                "memo" to mBinding.manualMemo.textTrim
            )
            .bindLifeCycle(getLifecycleOwner())
            .subscribeBySuccess(
                event = getViewModel(),
                onSuccess = {
                    showToast("提交成功！")

                    ActivityStack
                        .screenManager
                        .popActivities(
                            ManualMobileActivity::class.java,
                            ManualRepairActivity::class.java
                        )
                }
            )
    }

    /**
     * 添加商品
     */
    private fun cartAdd(
        productId: String,
        amount: String,
        quantity: String
    ) {
        getViewModel()
            .goodsEdit(
                BaseUrl.manuAdd,
                "id" to productId,
                "price" to amount,
                "quantity" to quantity,
                "memberId" to mMemberId
            )
            .bindLifeCycle(getLifecycleOwner())
            .subscribeBySuccess(
                event = getViewModel(),
                onSuccess = {
                    // 更新购物车
                    window.decorView.post { cartList() }

                    // 更新商品金额
                    getViewModel()
                        .cartCountFill(
                            mReceiverId,
                            mMemberId,
                            exchangeEnable,
                            mBinding
                        )
                }
            )
    }

    /**
     * 删除商品
     */
    private fun cartDelete(itemId: String) {
        showHintDialog(
            title = "删除商品",
            hint = "确定要删除该商品吗？",
            onSure = {
                getViewModel()
                    .goodsEdit(
                        BaseUrl.manuDel,
                        "id" to itemId
                    )
                    .bindLifeCycle(getLifecycleOwner())
                    .subscribeBySuccess(
                        event = getViewModel(),
                        onSuccess = {
                            // 更新购物车
                            window.decorView.post { cartList() }

                            // 更新商品金额
                            getViewModel()
                                .cartCountFill(
                                    mReceiverId,
                                    mMemberId,
                                    exchangeEnable,
                                    mBinding
                                )
                        }
                    )
            }
        )
    }

    /**
     * 修改商品
     */
    private fun cartModify(
        itemId: String,
        price: String,
        amount: String
    ) {
        getViewModel()
            .goodsEdit(
                BaseUrl.manuEdt,
                "id" to itemId,
                "quantity" to amount,
                "price" to price
            )
            .bindLifeCycle(getLifecycleOwner())
            .subscribeBySuccess(
                event = getViewModel(),
                onSuccess = {
                    // 更新购物车
                    window.decorView.post { cartList() }

                    // 更新商品金额
                    getViewModel()
                        .cartCountFill(
                            mReceiverId,
                            mMemberId,
                            exchangeEnable,
                            mBinding
                        )
                }
            )
    }

    /**
     * 商品列表
     */
    private fun cartList() {
        getViewModel()
            .cartList()
            .bindLifeCycle(getLifecycleOwner())
            .subscribeBySuccess(
                event = getViewModel(),
                onSuccess = {
                    val obj = JSONObject(it)
                    val objOrder = obj.optJSONArray("cartItems") ?: JSONArray()
                    mList.clear()
                    mList.addItems(
                        JsonUtil.toList(
                            objOrder.toString(),
                            OrderGoods::class.java
                        )
                    )

                    mGoodsCount.value = mList.size

                    mAdapter.setDataList(mList)
                }
            )
    }

    /**
     * 品牌选择弹框
     */
    private fun showBrandDialog() {
        val items = mBrandList
            .filter { outer ->
                mBrandCheckList.none { it.id == outer.id }
            }

        showListDialog(
            title = "请选择品牌",
            items = items.map { it.name },
            listener = { index, _ ->
                mBrandCheckList.add(0, items[index].copy())
                mBarrelAdapter.setDataList(mBrandCheckList)
            }
        )
    }

    /**
     * 品牌列表
     */
    private fun getBrandList(onFinish: () -> Unit) {
        getViewModel()
            .requestCommon(
                isLoading = true,
                requestUrl = BaseUrl.bucketPdt,
                requestMethod = HttpMethod.GET,
                onSuccess = { list ->
                    mBrandList.clear()

                    list.mapTo(mBrandList) {
                        ManualBarrel(it.id, it.name.orEmpty())
                    }

                    onFinish.invoke()
                }
            )
    }

    /**
     * 报单信息
     */
    override fun getData(index: Int, isLoading: Boolean) {
        getViewModel()
            .manualInfo(
                mReceiverId,
                mMemberId,
                exchangeEnable
            )
            .bindLifeCycle(getLifecycleOwner())
            .subscribeBySuccess(
                event = getViewModel(),
                onSuccess = { result ->
                    val obj = JSONObject(result)

                    mShopId = obj.optNotNull("shopId")
                    mAdminId = obj.optNotNull("adminId")
                    mAdminName = obj.optNotNull("adminName")

                    mBinding.apply {
                        // 商家备注
                        manualCmemo.text =
                            obj.optNotNull("cardMemo")
                                .notEmpty { manualCmemoLl.visible() }

                        manualWhere.setRightString(obj.optNotNull("shopName"))
                    }

                    // 更新收款金额
                    getViewModel().updatePriceFill(mBinding, obj)
                    // 购物车列表
                    cartList()

                    // 收货信息
                    val objReceive = obj.optJSONObject("receiver") ?: JSONObject()
                    mReceivePhone = objReceive.optNotNull("phone")
                    mReceiveLat = objReceive.optNotNull("lat")
                    mReceiveLng = objReceive.optNotNull("lng")
                }
            )
    }

    override fun onCheckedChanged(group: RadioGroup, checkedId: Int) {
        exchangeEnable = checkedId == R.id.manual_rb1

        mList.notEmpty {
            // 更新商品金额
            getViewModel()
                .cartCountFill(
                    mReceiverId,
                    mMemberId,
                    exchangeEnable,
                    mBinding
                )
        }
    }

}